package com.example.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.blog.dao.LiveInfoMapper;
import com.example.blog.dao.LiveUserMapper;
import com.example.blog.dto.AddUserReqDto;
import com.example.blog.dto.QueryUserReqDto;
import com.example.blog.dto.QueryUserResDto;
import com.example.blog.dto.base.IdRequestDto;
import com.example.blog.dto.UpdateUserReqDto;
import com.example.blog.dto.base.LoginReqDto;
import com.example.blog.dto.base.LoginResponseDto;
import com.example.blog.entity.LiveInfo;
import com.example.blog.entity.LiveUser;
import com.example.blog.response.CommonException;
import com.example.blog.response.ResponseModelDto;
import com.example.blog.response.ResponseModels;
import com.example.blog.service.LiveUserService;
import com.example.blog.util.ParamUtil;
import com.example.blog.util.RedisUtil;
import com.example.blog.util.ToolsUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * @author Admin
 */
@Service
public class LiveUserServiceImpl extends ServiceImpl<LiveUserMapper, LiveUser> implements LiveUserService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private LiveUserMapper baseMapper;

    private static final Integer ADMIN = 2;
    private static final Integer DELETE_USER = 9;

    @Override
    @Transactional
    public Boolean addUser(AddUserReqDto reqDto){
        if(ParamUtil.empty(reqDto.getName())){
            throw new CommonException("昵称不能为空");
        }
        if(ParamUtil.empty(reqDto.getName())){
            throw new CommonException("密码不能为空");
        }
        String account = ToolsUtil.getIntegerRound(10);
        //防止重复账号
        while (baseMapper.selectCount(Wrappers.lambdaQuery(LiveUser.class).eq(LiveUser::getAccount,account)) > 0){
            account = ToolsUtil.getIntegerRound(10);
        }
        String roomNo = ToolsUtil.getIntegerRound(6);
        //防止重复房间名
        while (baseMapper.selectCount(Wrappers.lambdaQuery(LiveUser.class).eq(LiveUser::getRoomNo,roomNo)) > 0){
            roomNo = ToolsUtil.getIntegerRound(6);
        }
        LiveUser liveUser = ToolsUtil.convertType(reqDto,LiveUser.class);
        liveUser.setId(ToolsUtil.getUUID());
        liveUser.setRoomNo(roomNo);
        //MD5加密
        liveUser.setPassword(ToolsUtil.getPasswordToMD5(reqDto.getPassword()));
        liveUser.setAccount(account);
        liveUser.setCreateTime(LocalDateTime.now());
        liveUser.setAdministrator(1);
        return baseMapper.insert(liveUser) > 0;
    }

    @Override
    @Transactional
    public Boolean updateUser(UpdateUserReqDto reqDto){
        LiveUser liveUser = ToolsUtil.convertType(reqDto,LiveUser.class);
        //MD5加密
        liveUser.setPassword(ToolsUtil.getPasswordToMD5(reqDto.getPassword()));
        return baseMapper.updateById(liveUser) > 0;
    }

    @Override
    @Transactional
    public Boolean deleteUser(IdRequestDto requestDto){
        LiveUser liveUser = baseMapper.selectById(requestDto.getId());
        //软删除
        liveUser.setStatus(9);
        return baseMapper.updateById(liveUser) > 0;
    }

    @Override
    @Transactional
    public IPage<QueryUserResDto> selectUser(QueryUserReqDto reqDto){
        LambdaQueryWrapper<LiveUser> wrapper = Wrappers.lambdaQuery(LiveUser.class);
        if(ParamUtil.notEmpty(reqDto.getRoomNo())){
            wrapper.like(LiveUser::getRoomNo,reqDto.getRoomNo());
        }
        if(ParamUtil.notEmpty(reqDto.getAccount())){
            wrapper.like(LiveUser::getAccount,reqDto.getAccount());
        }
        if(ParamUtil.notEmpty(reqDto.getName())){
            wrapper.like(LiveUser::getName,reqDto.getName());
        }
        Page<LiveUser> liveUserIPage = baseMapper.selectPage(reqDto.iPageInfo(), wrapper.ne(LiveUser::getStatus,9).orderByDesc(LiveUser::getCreateTime));
        IPage<QueryUserResDto> queryUserResDtoPage = ToolsUtil.convertType(liveUserIPage,QueryUserResDto.class);
        return queryUserResDtoPage;
    }

    @Override
    @Transactional
    public Boolean changeUserStatus(IdRequestDto requestDto){
        LiveUser liveUser = baseMapper.selectById(requestDto.getId());
        //启用禁用
        if(liveUser.getStatus() == 1){
            liveUser.setStatus(0);
        }else{
            liveUser.setStatus(1);
        }
        return baseMapper.updateById(liveUser) > 0;
    }

    @Override
    @Transactional
    public ResponseModelDto<LoginResponseDto> login(LoginReqDto reqDto){
        LiveUser user = baseMapper.selectOne(Wrappers.lambdaQuery(LiveUser.class)
                .eq(LiveUser::getAccount,reqDto.getAccount())
                .eq(LiveUser::getPassword,ToolsUtil.getPasswordToMD5(reqDto.getPassword()))
                .ne(LiveUser::getStatus,9));
        if(ParamUtil.empty(user)){
            return ResponseModels.loginException();
        }
        LoginResponseDto responseDto = new LoginResponseDto();
        responseDto.setToken(user.getId());
        String key = "cache_token_"+user.getId();
        //存储token，存活时间四小时
        if(!redisUtil.set(key,responseDto.getToken(),4*60*60)){
            throw new CommonException("redis执行失败");
        }
        responseDto.setId(user.getId());
        responseDto.setName(user.getName());
        responseDto.setRoomNo(user.getRoomNo());
        responseDto.setAdmin(Objects.equals(user.getAdministrator(), ADMIN));
        return ResponseModels.ok(responseDto);
    }

    @Override
    @Transactional
    public Boolean administrator(String userId){
        LiveUser liveUser = baseMapper.selectById(userId);
        if(ParamUtil.notEmpty(liveUser)){
            if(!liveUser.getStatus().equals(DELETE_USER)){
                return liveUser.getAdministrator().equals(ADMIN);
            }
        }
        return false;
    }

    @Override
    @Transactional
    public LiveUser selectUserById(String userId){
        LiveUser liveUser = baseMapper.selectOne(Wrappers.lambdaQuery(LiveUser.class).eq(LiveUser::getId,userId).ne(LiveUser::getStatus,9));
        return liveUser;
    }

}
